///在 测算或者报价发生变化的时候,动态计算对应的业务机会的 "项目类型"
///计算规则:
/*
	业务机会的项目类型由意向产品/报价产品/测算产品的产品线判断，计算规则如下：
	当有测算产品时，取最新测算产品数据进行计算；
	当没有测算产品时，取最新报价产品（含最新仪器报价产品及最新试剂报价产品）的数据进行计算；
	当没有测算产品和报价产品时，取意向产品的数据进行计算；
	当测算产品、报价产品、意向产品均为空时，项目类型为空。
	i.		单项目：单一产品线；
	ii.		多项目：两个及两个以上产品线；
	iii.	整体打包：三级以上医院5个及5个以上产品线，二级以上医院4及4个以上产品线
*/
public without sharing class OppSetProjectTypeHandler {
    public static void calcOppSetProjectType(Set<Id> oipSet) {

         Set<Id> oppSet = new Set<Id>();
        for(Opportunity opp : [select Id, Account.RecordType.Name ,RecordType.DeveloperName  from Opportunity where Id in:oipSet]){
            if(opp.Account.RecordType.Name.contains('海外'))continue;
            if(opp.RecordType.DeveloperName  == 'OverseaDearlerOpportunity' ||opp.RecordType.DeveloperName == 'DealerOpportunity')continue; 
            oppSet.add(opp.Id);

        }

        if(oppSet.size() == 0 )return ; 
    	///查找测算
        Map<Id,Measure_Calculate__c> mcMap = new Map<Id,Measure_Calculate__c>();
       for(Measure_Calculate__c mc : [select Id,Opportunity__c,CreatedDate from Measure_Calculate__c where Opportunity__c in:oppset]){

	       	if (!mcMap.containsKey(mc.Opportunity__c)) {
	       	    mcMap.put(mc.Opportunity__c, mc);    
	       	}else{//保存最新的测算
	       		Measure_Calculate__c beforeMc = mcMap.get(mc.Opportunity__c);
	       		if(beforeMc.CreatedDate < mc.CreatedDate)mcMap.put(mc.Opportunity__c, mc);
	       	}

       }
        ///计算测算情况下 的业务机会的项目类型
       if(mcMap.values().size() > 0)setOppProjectTypeMc(mcMap.values());
       ///
       Set<Id> resOpps= new Set<Id>();
      	for (Id opp : oppset) {
      		if(mcMap.get(opp) == null)resOpps.add(opp);
      	}

      	///如果还有剩余的业务机会 查找符合条件的报价
      	if(resOpps.size() > 0){
      		///
      		Map<Id,Quote>  qMap= new Map<Id,Quote>([select Id,OpportunityId ,CreatedDate from Quote where OpportunityId in:resOpps]);
          
              for (Quote q : qMap.values()) {
                if (resOpps.contains(q.OpportunityId)) {
                    resOpps.remove(q.OpportunityId);
                }

              }
      		

      		///计算报价情况下的 业务机会的项目类型
      		if(qMap.values().size() >0)setOppProjectTypeQuote(qMap);
      		


      		///如果还有剩余的业务机会
      		if (resOpps.size() > 0) {

      			setOppProjectTypeIntent(resOpps);
      		}

      	}

    }

    ///计算 意向产品情况下的业务机会的 项目类型
	public static void setOppProjectTypeIntent(Set<Id> oipSet) {
        Set<Id> accSet = new Set<Id>();
        Set<String> ipc1Set = new Set<String>();

        Map<Id, Opportunity> accMap = new Map<Id, Opportunity >([select Id, AccountId, Account.Level__c from Opportunity where Id in :oipSet]);
    
        Map<Id, List<IntentProduct__c>> ipMap = new Map<Id, List<IntentProduct__c>>();
        for (IntentProduct__c ip : [select Id, NewCategory1__c, Product__r.Category1__c, Opportunity__c, Opportunity__r.AccountId, Comment__c from IntentProduct__c where Opportunity__c in: oipSet]) {
            List<IntentProduct__c> ipList = new List<IntentProduct__c>();
            if (ipMap.containsKey(ip.Opportunity__c) == true) { 
                ipList = ipMap.get(ip.Opportunity__c);
            }   
            ipList.add(ip);
            ipMap.put(ip.Opportunity__c, ipList);
        }

        List<Opportunity> opList = new List<Opportunity>();
        for (Id oid : oipSet) {
            Opportunity op = new Opportunity(Id = oid);
            String level = String.valueOf(accMap.get(oid).Account.Level__c);
            
            List<IntentProduct__c> ipList = ipMap.get(oid);
            if (ipList != null) {
                for ( IntentProduct__c  ipt : ipList ) {
                    ipc1Set.add(ipt.Product__r.Category1__c);
                    System.debug(ipt.Product__r.Category1__c);
                }
                System.debug(ipc1Set);
            }
            op.ProjectType__c  = IPQPMECPHandler.calcOppProjectType(level, ipc1Set);
            System.debug(op.ProjectType__c);
            opList.add(op);
        }
        System.debug('意向计算');
        update opList;
    }

///计算 报价情况下 业务机会的 项目类型
public static void setOppProjectTypeQuote(Map<Id, Quote> qMap) {
        Set<Id> oidSet = new Set<Id>();
        Set<Id> newqtidSet = new Set<Id>();
        Set<String> qpc1Set = new Set<String>();

        for (Quote q : qMap.values()) {
            oidSet.add(q.OpportunityId);
        }


        //查询相关客户下的客户等级 
        Map<Id, Opportunity> oppMap = new  Map<Id, Opportunity>([SELECT Id,AccountId, Account.Level__c FROM Opportunity WHERE Id IN :oidSet  ]);
        
        //查询相关业务机会下最新的仪器报价
        for ( Quote qt : [ SELECT Id FROM Quote WHERE OpportunityID IN: oidSet AND Type__c = '仪器报价' Order By LastModifiedDate DESC limit 1 ] ) {
            newqtidSet.add(qt.Id);
        }
        //查询相关业务机会下最新的试剂报价
        for ( Quote qt : [ SELECT Id FROM Quote WHERE OpportunityID IN: oidSet AND Type__c = '试剂报价' Order By LastModifiedDate DESC limit 1 ] ) {
            newqtidSet.add(qt.Id);
        }
        
        Map<Id, List<QuoteProduct__c>> qpMap = new Map<Id, List<QuoteProduct__c>>();
        for ( QuoteProduct__c qp : [ SELECT Id, Product__r.Category1__c, Quote__r.OpportunityId FROM QuoteProduct__c WHERE 
                    Quote__c IN :newqtidSet ] ) {
            List<QuoteProduct__c> qplist =  new List<QuoteProduct__c>();
            Id oppid = qp.Quote__r.OpportunityId;           
            
            if ( qpMap.containsKey(oppid) == true ) {
                qplist = qpMap.get(oppid);   
            }
            qpList.add(qp);
            qpMap.put(oppid, qpList);
        }

        List<Opportunity> oppList = new List<Opportunity>();
        for ( Id oid : oidSet ) {
            Opportunity opp = new Opportunity(Id = oid);            
            String level = String.valueOf(oppMap.get(oid).Account.Level__c);
            
            List<QuoteProduct__c> qplist = qpMap.get(oid);            
            if(qplist != null){
                for (QuoteProduct__c qp : qplist ) {
                    qpc1Set.add(qp.Product__r.Category1__c);                    
                }
            }
            opp.ProjectType__c  = IPQPMECPHandler.calcOppProjectType(level, qpc1Set);
            oppList.add(opp);
        }
       System.debug('报价计算');

        update oppList;
    }

        ///计算测算情况下 的业务机会的项目类型
   public static void setOppProjectTypeMc(List<Measure_Calculate__c> newList) {

        Map<Id,Id>  oppMap= new Map<Id,Id>();
        for (Measure_Calculate__c mc : newList) {
                oppMap.put(mc.Opportunity__c, mc.Id);
            
        }
        System.debug('***'+oppMap);
        Map<Id,Set<String>>  cateMaps = new Map<Id,Set<String>>();
        Map<Id,String> accLevelMap = new Map<Id,String>();
        

               ///计算项目类型
        for (Measure_Calculate_Product__c mcp: [select Id,Product__r.Category1__c ,Measure_Calculate__r.Opportunity__c,Measure_Calculate__r.Opportunity__r.Account.Level__c from Measure_Calculate_Product__c where Measure_Calculate__c in:oppMap.values() ]) {
                if (!cateMaps.containsKey(mcp.Measure_Calculate__r.Opportunity__c)) {
                    cateMaps.put(mcp.Measure_Calculate__r.Opportunity__c, new Set<String>());
                }
                accLevelMap.put(mcp.Measure_Calculate__r.Opportunity__c, mcp.Measure_Calculate__r.Opportunity__r.Account.Level__c);
                cateMaps.get(mcp.Measure_Calculate__r.Opportunity__c).add(mcp.Product__r.Category1__c);
               // System.debug('测算产品'+ mcp);


        }
        System.debug(cateMaps);
        ///更新业务机会的项目类型
        List<Opportunity> oppList = new List<Opportunity>();
        for (Id oppId :cateMaps.keySet()  ) {
            if (oppId != null) {
                 Opportunity opp = new Opportunity();
                 opp.Id = oppId;
                 opp.ProjectType__c = IPQPMECPHandler.calcOppProjectType(accLevelMap.get(oppId), cateMaps.get(oppId));
                oppList.add(opp);
            }

        }
       System.debug('测算计算');

        if (oppList.size()>0) update oppList; 


   }



}